package com.kye.express.business.login;


import android.content.Context;
import android.os.SystemClock;

import com.kye.express.BuildConfig;
import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.ErrorView;
import com.kye.express.contract.base.view.IView;
import com.kye.express.contract.base.view.LoadingView;
import com.kye.express.utils.MobileID;
import com.kye.model.OpenApiResultObserver;
import com.kye.model.SharedPreferencesConfig;
import com.kye.model.SharedPreferencesManager;
import com.kye.model.UserSession;
import com.kye.model.base.RetrofitManager;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.user.User;
import com.kye.model.bean.user.request.RequestBindJpushIdBean;
import com.kye.model.bean.user.request.RequestGetImageVerificationCode;
import com.kye.model.bean.user.request.RequestGetSmsVerificationCode;
import com.kye.model.bean.user.request.RequestLoginWithSmsVerificationCode;
import com.kye.model.service.UserService;

import cn.jpush.android.api.JPushInterface;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

import static com.kye.express.business.login.LoginContract.LoginView.GET_VERIFICATION_CODE_INTERVAL;
import static com.kye.express.business.login.LoginContract.LoginView.LAST_VERIFICATION_TIME;

public interface LoginContract {

    interface LoginView extends IView, LoadingView, ErrorView {

        Long GET_VERIFICATION_CODE_INTERVAL = 60L;
        String LAST_VERIFICATION_TIME = SharedPreferencesConfig.LAST_VERIFICATION_TIME;

        void onGotSmsVerificationCode();

        void onLogined(User user);

        void onGotImageVerificationCode(byte[] bytes);

        void onCountDown(Long seconds);

        void onCompleteInformation(User user);

        Context getContext();
    }

    class LoginPresenter extends BasePresenter<LoginView> {

        @Override
        public void bind(LoginView view) {
            super.bind(view);
            checkNeedCountDown();
        }

        /**
         * 初始化检查上次计时
         */
        private void checkNeedCountDown() {
            long current = SystemClock.uptimeMillis();
            long verificationTime = SharedPreferencesManager.get(LoginView.LAST_VERIFICATION_TIME, 0L);

            if (verificationTime <= current) return;

            final long seconds = (verificationTime - current) / 1000;

            if (seconds > GET_VERIFICATION_CODE_INTERVAL) return;

            getView().onCountDown(seconds);
        }

        public void getSmsVerificationCode(final String phone, String imageVerificationCode) {
            RetrofitManager.getInstance()
                    .createOpenApiService(UserService.class)
                    .getSmsVerificationCode(new RequestGetSmsVerificationCode(phone, imageVerificationCode))
                    .compose(getView().<OpenApiResult<Object>>bindToLifecycleDestroy())
                    .doOnSuccess(new Consumer<OpenApiResult<Object>>() {
                        @Override
                        public void accept(OpenApiResult<Object> objectOpenApiResult) throws Exception {
                            SharedPreferencesManager.commit(LAST_VERIFICATION_TIME, SystemClock.uptimeMillis() + GET_VERIFICATION_CODE_INTERVAL * 1000);
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<Object>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<Object> result, Object o) {
                            getView().onGotSmsVerificationCode();
                            getView().onLoaded();
                        }

                        @Override
                        public void onApiError(OpenApiResult<Object> result, int code, String msg) {
//                            if (code == 6029) {
                            if (code == 15747) {
                                getImageVerificationCode(phone);
                            } else {
                                getView().onError(msg);
                                getView().onLoaded();
                            }
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError();
                            getView().onLoaded();
                        }

                        @Override
                        public void onLoaded() {

                        }
                    });
        }

        public void loginOrRegister(String phone, String verificationCode) {
            RetrofitManager.getInstance()
                    .createOpenApiService(UserService.class)
                    .loginWithSmsVerificationCode(new RequestLoginWithSmsVerificationCode(phone, verificationCode), MobileID.get(), BuildConfig.VERSION_NAME)
                    .compose(getView().<OpenApiResult<User>>bindToLifecycleDestroy())
                    .doOnSuccess(new Consumer<OpenApiResult<User>>() {
                        @Override
                        public void accept(OpenApiResult<User> userOpenApiResult) throws Exception {
                            User user = userOpenApiResult.getData();
                            if (user != null && !user.isBlack()) {
                                UserSession.getInstance().setUser(user);
                                bindJpushId(phone);
                            }
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<User>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<User> result, User user) {
                            if (user.isBlack()) {
                                getView().onCompleteInformation(user);
                                return;
                            }

                            getView().onLogined(user);
                        }

                        @Override
                        public void onApiError(OpenApiResult<User> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError();
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        public void getImageVerificationCode(String phone) {
            RetrofitManager.getInstance()
                    .createOpenApiService(UserService.class)
                    .getImageVerificationCode(new RequestGetImageVerificationCode(phone))
                    .compose(getView().<OpenApiResult<byte[]>>bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<byte[]>() {

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError();
                        }

                        @Override
                        public void onLoading(Disposable d) {

                        }

                        @Override
                        public void onSuccess(OpenApiResult<byte[]> result, byte[] bytes) {
                            getView().onGotImageVerificationCode(bytes);
                        }

                        @Override
                        public void onApiError(OpenApiResult<byte[]> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        /**
         * 绑定jpush registration id 到服务器
         *
         * @param phone
         */
        public void bindJpushId(String phone) {
            RetrofitManager.getInstance()
                    .createOpenApiService(UserService.class)
                    .bindJpushId(new RequestBindJpushIdBean(JPushInterface.getRegistrationID(getView().getContext()), phone))
                    .compose(getView().<OpenApiResult<Object>>bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<Object>() {

                        @Override
                        public void onOtherError(Throwable e) {
                        }

                        @Override
                        public void onLoading(Disposable d) {

                        }

                        @Override
                        public void onSuccess(OpenApiResult<Object> result, Object bytes) {
                        }

                        @Override
                        public void onApiError(OpenApiResult<Object> result, int code, String msg) {
                        }

                        @Override
                        public void onLoaded() {
                        }
                    });
        }
    }

}
